package filenavigation

import (
	"errors"
	"fmt"
	"github.com/goccy/go-json"
	"github.com/gogf/gf/errors/gerror"
	"gitlab.local/DO-module/new-filemanage-module/src/constant"
	"gitlab.local/TerraMaster/tos-modules/fileoperate"
	"gitlab.local/TerraMaster/tos-modules/tosconfig"
	"gitlab.local/golibrary/linux"
	"gitlab.local/golibrary/user"
	"gitlab.local/golibrary/utils"
	"os"
	"path/filepath"
	"strings"
)

type App struct {
	Icon              string      `json:"icon"`             //窗口图标
	ID                string      `json:"id"`               //窗口唯一id
	Name              interface{} `json:"name"`             //窗口标题："meto", "menu_Control"
	State             bool        `json:"state"`            //默认是否打开
	MaxMin            bool        `json:"maxmin"`           //是否显示放大缩小
	Width             int         `json:"width,omitempty"`  //窗体宽度
	Height            int         `json:"height,omitempty"` //窗体高度
	OpenPath          bool        `json:"open_path"`        //控制是否新窗口打开
	HideTitle         int         `json:"hideTitle"`        //控制是否隐藏标题栏
	Resize            bool        `json:"resize"`           //是否可改变大小
	Role              []string    `json:"role"`             //支持哪些角色查看
	Type              string      `json:"type"`             //窗口类型：Control:没有侧边栏, tab:有左右边,iframe:兼容老版本
	Components        string      `json:"components"`       //有即为新式组件
	Path              string      `json:"path"`             //兼容旧式页面，设置即用iframe加载相应path
	Help              string      `json:"help"`             //是否有帮助
	IsDelete          bool        `json:"is_delete"`        //是否可删除
	Children          []*App      `json:"children"`
	DesktopShow       bool        `json:"desktopShow"`       //是否桌面展示
	NavigationBarShow bool        `json:"navigationBarShow"` //是否导航栏展示展示
	TypesOf           string      `json:"typesOf"`           //种类
	ParentId          string      `json:"parentId"`          //父类id
	IsCustom          bool        `json:"isCustom"`
	Content           []string    `json:"content"`
	ClassName         string      `json:"className"`
}

type ExtendApp struct {
	Icon              string      `json:"icon"`              // 窗口图标
	ID                string      `json:"id"`                // 窗口唯一id
	Path              string      `json:"path"`              // 兼容旧式页面，设置即用iframe加载相应path
	Name              interface{} `json:"name"`              // 窗口标题："meto", "menu_Control"
	MaxMin            bool        `json:"maxmin"`            // 是否显示放大缩小
	Width             int         `json:"width,omitempty"`   // 窗体宽度
	Height            int         `json:"height,omitempty"`  // 窗体高度
	Exec              bool        `json:"exec"`              // 控制是否需要启动
	OpenPath          bool        `json:"open_path"`         // 控制是否新窗口打开
	Resize            bool        `json:"resize"`            // 是否可改变大小
	State             bool        `json:"state"`             // 默认是否打开
	Reset             bool        `json:"reset"`             // 是否需要重置功能
	Type              string      `json:"type"`              // 窗口类型：Control:没有侧边栏, tab:有左右边, iframe:兼容老版本
	Help              string      `json:"help"`              // 是否有帮助
	Depend            []string    `json:"depend"`            // 是否有依赖
	IsDelete          bool        `json:"is_delete"`         // 是否可删除
	RealFile          string      `json:"-"`                 // 程序内部使用 应用快捷方式的真实路径
	DesktopShow       bool        `json:"desktopShow"`       // 是否桌面展示
	NavigationBarShow bool        `json:"navigationBarShow"` // 是否导航栏展示展示
	TypesOf           string      `json:"typesOf"`           // 种类
	Category          string      `json:"category"`          //类别：默认 Utilities（实用工具），其它 Security（安全），Multimedia（多媒体）Development_tools（开发工具），Business（商业），Backup（备份）
	Size              int64       `json:"size"`              //字节B
	SizeFriendly      string      `json:"size_friendly"`     //文件大小(友好)
	CTime             string      `json:"c_time"`            //创建时间
}

type QuickConnectionInfo struct {
	Id          string `json:"id"`          //连接的id
	Name        string `json:"name"`        //快捷连接的名称
	Path        string `json:"path"`        //快捷连接的地址
	OpenPath    bool   `json:"open_path"`   //是否打开状态
	Icon        string `json:"icon"`        //图片地址
	TypesOf     string `json:"typesOf"`     //种类
	DesktopShow bool   `json:"desktopShow"` //是否桌面展示//是否桌面展示
	BgColor     string `json:"bgColor"`
	CTime       string `json:"create_time"` //创建时间
}

type NewQuickConnectionInfo struct {
	Id string `json:"id"` //连接的id
	fileoperate.FoldersInfo
}

// AppShowStatusInfo
// @Description: 记录用户的桌面应用展示状态
type AppShowStatusInfo struct {
	ID            string
	Desktop       bool //桌面
	NavigationBar bool //导航条
}

var icons = map[string]string{ //快捷方式图标列表
	"folder": "/static/images/desktop/folder.svg",
	"file":   "/static/images/file_manager/file.svg",
	"txt":    "/static/images/file_manager/txt.svg",
	"zip":    "/static/images/file_manager/zip_rar.svg",
	"php":    "/static/images/file_manager/php.svg",
	"html":   "/static/images/file_manager/file.svg",
	"ini":    "/static/images/file_manager/file.svg",
	"mp4":    "/static/images/file_manager/mp4.svg",
	"pdf":    "/static/images/file_manager/pdf.svg",
	"mp3":    "/static/images/file_manager/mp3.svg",
	"image":  "/static/images/file_manager/jpg.svg",
}

// CreateDesktopFolder 创建桌面(文件、文件夹、快捷方式)
// t 1文件 2文件夹 3快捷方式
func (n *FileNav) CreateDesktopFolder(paths []string, userName string, t int8) error {

	/*dir, err := n.GetUserShortcutDir(userName)
	if err != nil {
		return gerror.Wrap(err, "CreateDesktopFolder")
	}
	if err = os.MkdirAll(dir, 0755); err != nil {
		return gerror.Wrap(err, "CreateDesktopFolder1")
	}*/
	dir, err := n.GetDesktopDir(userName)
	if err != nil {
		return gerror.Wrap(err, "CreateDesktopFolder fail")
	}
	for _, v := range paths {
		switch t {
		case 3:
			_ = n.CreateOexeFile(v, 0, dir)
		default:
			_, _ = n.fOptGetter.CreateFolder(filepath.Join(dir, filepath.Base(v)), t)
		}
	}

	return nil
}

// DeleteDesktopFile 删除桌面文件（创建的文件、文件夹、快捷方式）
func (n *FileNav) DeleteDesktopFile(fName, userName string) error {
	//dir, err := n.GetUserShortcutDir(userName)
	dir, err := n.GetDesktopDir(userName)
	if err != nil {
		return gerror.Wrap(err, "DeleteDesktopFile")
	}
	return os.Remove(filepath.Join(dir, fName+".oexe"))
}

// GetDesktopDir 获取桌面目录
func (n *FileNav) GetDesktopDir(userName string) (string, error) {
	dir := fmt.Sprintf(constant.DesktopFile, linux.GetMainVolume(), userName)
	if !utils.Exists(dir) {
		if err := os.MkdirAll(dir, 0755); err != nil {
			return "", gerror.Wrap(err, "CreateDesktopFolder1")
		}
	}
	return dir, nil
}

func (n *FileNav) GetUserShortcutDir(userName string) (string, error) {
	lookup, err := user.Lookup(userName)
	if err != nil {
		return "", gerror.Wrap(err, "getUserConfigDir")
	}
	dir, err := tosconfig.GetUserConfigDir(lookup.Username)
	if err != nil {
		return "", gerror.Wrap(err, "getUserConfigDir1")
	}
	return filepath.Join(dir, "shortcut"), nil
}

// CreateOexeFile 创建快捷方式(oexe文件)
// oexe类型文件无法再创建oexe类型文件
// t  默认oexe 1为app_link
// outDir 输出目录 没有为dir文件所在目录
func (n *FileNav) CreateOexeFile(dir string, t int8, outDir ...string) error {
	//判断文件存在
	if !utils.Exists(dir) {
		return errors.New("the path error")
	}
	ext := filepath.Ext(dir)
	//判断是否是oexe类型文件
	if ext == ".oexe" {
		return errors.New("the oexe file could not create a shortcut")
	}
	//图标
	fileInfo, err := os.Stat(dir)
	if err != nil {
		return gerror.Wrap(err, "CreateOexeFile")
	}
	icon := ""
	if fileInfo.IsDir() {
		icon = icons["folder"]
	} else {
		//获取文件归类
		classify, err := utils.FileClassify(dir)
		if err != nil {
			return gerror.Wrap(err, "CreateOexeFile1")
		}
		//图像
		if classify == utils.Image {
			icon = icons["image"]
		}
		//视频
		if classify == utils.Video {
			icon = icons["mp4"]
		}
		//音频
		if classify == utils.Audio {
			icon = icons["mp3"]
		}
		//其他
		s, b := icons[utils.GetFileExt(dir)]
		if b {
			icon = s
		}
	}
	//默认图标
	if icon == "" {
		icon = icons["file"]
	}
	//写入内容
	types := "oexe"
	if t == 1 {
		types = "app_link"
	}
	data, err := json.Marshal(utils.OexeDate{
		Type: types,
		Link: dir,
		Icon: icon,
	})
	if err != nil {
		return gerror.Wrap(err, "CreateOexeFile2")
	}
	//替换文件扩展名
	src, file := filepath.Split(dir)
	if file != ext {
		file = strings.TrimSuffix(file, ext) + ".oexe"
	} else {
		file += ".oexe"
	}
	if len(outDir) > 0 && len(outDir[0]) > 0 {
		d, err := os.Stat(outDir[0])
		if err == nil && d.IsDir() {
			src = filepath.Join(outDir[0], file)
		}
	} else {
		src = filepath.Join(src, file)
	}
	src, err = utils.AutoFolderName(src)
	if err != nil {
		return gerror.Wrap(err, "CreateOexeFile3")
	}
	return os.WriteFile(src, data, os.ModePerm)
}
